<!-- tab组件: <cc-tabs v-model="tabIndex" :tabs="tabs" @change="tabChange"></cc-tabs> -->
<template>
	<view class="cc-tabs" :class="{ 'tabs-fixed': fixed }" :style="{ height: tabHeightVal, top: topFixed, 'margin-top': topMargin }">
		<scroll-view v-if="tabs.length" :id="viewId" :scroll-left="scrollLeft" scroll-x scroll-with-animation :scroll-animation-duration="240">
			<view class="tabs-item" :class="{ 'tabs-flex': !isScroll, 'tabs-scroll': isScroll }">
				<!-- tab -->
				<view
					class="tab-item"
					:class="{ active: tabIndex === i }"
					:style="{ height: tabHeightVal, marginLeft: spaceLeft + 'px', 'border-color': myColor, 'line-height': tabHeightVal }"
					v-for="(tab, i) in tabs"
					:key="i"
					@click="tabClick(i)"
				>
					{{ getTabName(tab) }}
				</view>
			</view>
		</scroll-view>
	</view>
</template>

<script>
export default {
	props: {
		tabs: {
			// 支持格式: ['全部', '待付款'] 或 [{name:'全部'}, {name:'待付款'}]
			type: Array,
			default() {
				return [];
			}
		},
		// 取name的字段
		nameKey: {
			type: String,
			default: 'name'
		},

		// 间隔距离
		spaceLeft: {
			type: [String, Number],
			default: 12
		},
		// 下划线颜色
		myColor: {
			type: String,
			default: '#FB4E47'
		},
		tabIndex: {
			// 当前显示的下标 (使用v-model语法糖: 1.props需为tabIndex; 2.需回调input事件)
			type: [String, Number],
			default: 0
		},
		// 是否悬浮,默认false
		fixed: Boolean,

		// tabs高度
		height: {
			// 高度,单位rpx
			type: [String, Number],
			default: 72
		},
		// 顶部偏移的距离,默认单位rpx (当fixed=true时,已加上windowTop)
		top: {
			type: Number,
			default: 0
		}
	},
	data() {
		return {
			viewId: 'id_' + Math.random().toString(36).substr(2, 16),
			scrollLeft: 0,
			windowWidth: 0,
			windowTop: 0,
			warpWidth: null
		};
	},
	computed: {
		isScroll() {
			return 1; // 指定了tabWidth的宽度,则支持水平滑动
		},
		tabHeightPx() {
			return uni.upx2px(this.height);
		},
		tabHeightVal() {
			return this.tabHeightPx + 'px';
		},
		tabWidthPx() {
			return uni.upx2px(200);
		},
		tabWidthVal() {
			return this.isScroll ? this.tabWidthPx + 'px' : '';
		},
		lineLeft() {
			if (this.isScroll) {
				return this.tabWidthPx * this.tabIndex + this.tabWidthPx / 2 + 'px'; // 需转为px (用rpx的话iOS真机显示有误差)
			} else {
				return (100 / this.tabs.length) * (this.tabIndex + 1) - 100 / (this.tabs.length * 2) + '%';
			}
		},
		topFixed() {
			return this.fixed ? this.windowTop + uni.upx2px(this.top) + 'px' : 0;
		},
		topMargin() {
			return this.fixed ? 0 : this.top + 'rpx';
		}
	},
	watch: {
		tabs() {
			this.warpWidth = null; // 重新计算容器宽度
			this.scrollCenter(); // 水平滚动到中间
		},
		tabIndex() {
			this.scrollCenter(); // 水平滚动到中间
		}
	},
	created() {
		let sys = uni.getSystemInfoSync();
		this.windowWidth = sys.windowWidth;
		this.windowTop = sys.windowTop;
	},
	mounted() {
		this.scrollCenter(); // 滚动到当前下标
	},
	methods: {
		getTabName(tab) {
			return typeof tab === 'object' ? tab[this.nameKey] : tab;
		},
		tabClick(i) {
			if (this.tabIndex != i) {
				this.$emit('input', i);
				this.$emit('change', i);
			}
		},
		async scrollCenter() {
			if (!this.isScroll) return;
			if (!this.warpWidth) {
				// tabs容器的宽度
				let rect = await this.initWarpRect();
				this.warpWidth = rect ? rect.width : this.windowWidth; // 某些情况下取不到宽度,暂时取屏幕宽度
			}
			let tabLeft = this.tabWidthPx * this.tabIndex + this.tabWidthPx / 2; // 当前tab中心点到左边的距离
			let diff = tabLeft - this.warpWidth / 2; // 如果超过tabs容器的一半,则滚动差值
			this.scrollLeft = diff - 160;

			// #ifdef MP-TOUTIAO
			this.scrollTimer && clearTimeout(this.scrollTimer);
			this.scrollTimer = setTimeout(() => {
				// 字节跳动小程序,需延时再次设置scrollLeft,否则tab切换跨度较大时不生效
				this.scrollLeft = Math.ceil(diff);
			}, 400);
			// #endif
		},
		initWarpRect() {
			return new Promise((resolve) => {
				setTimeout(() => {
					// 延时确保dom已渲染, 不使用$nextclick
					let query = uni.createSelectorQuery();
					// #ifndef MP-ALIPAY
					query = query.in(this); // 支付宝小程序不支持in(this),而字节跳动小程序必须写in(this), 否则都取不到值
					// #endif
					query
						.select('#' + this.viewId)
						.boundingClientRect((data) => {
							resolve(data);
						})
						.exec();
				}, 20);
			});
		}
	}
};
</script>

<style lang="scss" scoped>
.cc-tabs {
	position: relative;
	font-size: 15px;
	font-family: PingFangSC-Medium, PingFang SC;
	font-weight: 500;

	box-sizing: border-box;
	overflow-y: hidden;
	margin-left: -8px;
	color: rgba(255, 255, 255, 0.6);

	&.tabs-fixed {
		z-index: 990;
		position: fixed;
		left: 0;
		width: 100%;
	}

	.tabs-item {
		transition: all 1s;
		position: relative;
		white-space: nowrap;
		padding-bottom: 10px; // 撑开高度,再配合cc-tabs的overflow-y: hidden,以达到隐藏滚动条的目的
		box-sizing: border-box;
		display: flex;
		justify-content: space-around;
		align-items: center;
		.tab-item {
			position: relative;
			text-align: center;
			box-sizing: border-box;
			font-weight: 400;
			// 设置文字标题左右多出6px
			padding: 0px 6px;
			color: #000000;
			background-color: #ffffff;
			margin-left: 12px;
			font-size: 14px;
			font-family: PingFangSC-Regular, PingFang SC;

			&.active {
				color: #fb4e47 !important;
				font-family: PingFangSC-Regular, PingFang SC;
				font-weight: 660;
				font-size: 14px;
				border-bottom: 3px solid;
				border-color: '#3F70FF';
			}
		}
	}

	// 平分的方式显示item
	.tabs-flex {
		display: flex;

		.tab-item {
			flex: 1;
		}
	}

	// 居左显示item,支持水平滑动
	.tabs-scroll {
		.tab-item {
			display: inline-block;
		}
	}
}
</style>
